// 扫码登录后端API实现示例
// 使用 Node.js + Express + Redis

const express = require('express');
const QRCode = require('qrcode');
const redis = require('redis');
const jwt = require('jsonwebtoken');
const { v4: uuidv4 } = require('uuid');

const app = express();
const redisClient = redis.createClient();

// 中间件
app.use(express.json());

// 1. 生成二维码API
app.post('/api/qrcode/generate', async (req, res) => {
    try {
        const qrCodeId = uuidv4();
        const timestamp = Date.now();
        
        // 生成二维码内容（通常是登录URL）
        const qrCodeUrl = `https://yourapp.com/qr-login?code=${qrCodeId}&t=${timestamp}`;
        
        // 生成二维码图片
        const qrCodeImage = await QRCode.toDataURL(qrCodeUrl, {
            width: 200,
            margin: 2,
            color: {
                dark: '#000000',
                light: '#FFFFFF'
            }
        });
        
        // 将二维码信息存储到Redis，设置过期时间（5分钟）
        await redisClient.setex(`qrcode:${qrCodeId}`, 300, JSON.stringify({
            status: 'pending',
            createdAt: timestamp,
            expiresAt: timestamp + 300000 // 5分钟后过期
        }));
        
        res.json({
            success: true,
            qrCodeId: qrCodeId,
            qrCodeUrl: qrCodeUrl,
            qrCodeImage: qrCodeImage
        });
    } catch (error) {
        console.error('生成二维码失败:', error);
        res.status(500).json({
            success: false,
            message: '生成二维码失败'
        });
    }
});

// 2. 检查二维码状态API
app.get('/api/qrcode/status/:qrCodeId', async (req, res) => {
    try {
        const { qrCodeId } = req.params;
        
        // 从Redis获取二维码状态
        const qrCodeData = await redisClient.get(`qrcode:${qrCodeId}`);
        
        if (!qrCodeData) {
            return res.json({
                success: true,
                status: 'expired'
            });
        }
        
        const data = JSON.parse(qrCodeData);
        
        // 检查是否过期
        if (Date.now() > data.expiresAt) {
            await redisClient.del(`qrcode:${qrCodeId}`);
            return res.json({
                success: true,
                status: 'expired'
            });
        }
        
        res.json({
            success: true,
            status: data.status,
            userInfo: data.userInfo || null
        });
    } catch (error) {
        console.error('检查二维码状态失败:', error);
        res.status(500).json({
            success: false,
            message: '检查状态失败'
        });
    }
});

// 3. 移动端扫码确认API
app.post('/api/qrcode/confirm', async (req, res) => {
    try {
        const { qrCodeId, userId, token } = req.body;
        
        // 验证移动端用户token
        const decoded = jwt.verify(token, process.env.JWT_SECRET);
        
        // 检查二维码是否存在且未过期
        const qrCodeData = await redisClient.get(`qrcode:${qrCodeId}`);
        
        if (!qrCodeData) {
            return res.status(400).json({
                success: false,
                message: '二维码不存在或已过期'
            });
        }
        
        const data = JSON.parse(qrCodeData);
        
        if (data.status !== 'pending' && data.status !== 'scanned') {
            return res.status(400).json({
                success: false,
                message: '二维码状态异常'
            });
        }
        
        // 获取用户信息
        const userInfo = {
            id: decoded.userId,
            username: decoded.username,
            role: decoded.role,
            avatar: decoded.avatar
        };
        
        // 生成PC端登录token
        const pcToken = jwt.sign(userInfo, process.env.JWT_SECRET, { expiresIn: '24h' });
        
        // 更新二维码状态为已确认
        await redisClient.setex(`qrcode:${qrCodeId}`, 300, JSON.stringify({
            ...data,
            status: 'confirmed',
            userInfo: {
                ...userInfo,
                token: pcToken
            }
        }));
        
        res.json({
            success: true,
            message: '确认登录成功'
        });
    } catch (error) {
        console.error('确认登录失败:', error);
        res.status(500).json({
            success: false,
            message: '确认登录失败'
        });
    }
});

// 4. 移动端扫码API（模拟）
app.post('/api/qrcode/scan', async (req, res) => {
    try {
        const { qrCodeId } = req.body;
        
        // 检查二维码是否存在
        const qrCodeData = await redisClient.get(`qrcode:${qrCodeId}`);
        
        if (!qrCodeData) {
            return res.status(400).json({
                success: false,
                message: '二维码不存在或已过期'
            });
        }
        
        const data = JSON.parse(qrCodeData);
        
        if (data.status !== 'pending') {
            return res.status(400).json({
                success: false,
                message: '二维码已被使用'
            });
        }
        
        // 更新状态为已扫描
        await redisClient.setex(`qrcode:${qrCodeId}`, 300, JSON.stringify({
            ...data,
            status: 'scanned'
        }));
        
        res.json({
            success: true,
            message: '扫码成功，请在手机上确认登录'
        });
    } catch (error) {
        console.error('扫码失败:', error);
        res.status(500).json({
            success: false,
            message: '扫码失败'
        });
    }
});

// 5. 清理过期二维码的定时任务
setInterval(async () => {
    try {
        // 这里可以实现清理过期二维码的逻辑
        // 由于Redis设置了过期时间，会自动清理
        console.log('清理过期二维码...');
    } catch (error) {
        console.error('清理过期二维码失败:', error);
    }
}, 60000); // 每分钟执行一次

// 启动服务器
const PORT = process.env.PORT || 3000;
app.listen(PORT, () => {
    console.log(`扫码登录服务运行在端口 ${PORT}`);
});

module.exports = app;
